import useStateRef from '@/hooks/useStateRef'
import PauseSvg from '@/svg/PauseSvg'
import PlaySvg from '@/svg/PlaySvg'
import { loadImageInfo } from '@/utils/loadVideo'
import { useEffect, useRef, useState } from 'react'
import { showToast } from '@/utils/toast'
import imageLoadManager from '@/lib/imageLoadManager'
import CustomCanvas from '@/component/CustomCanvas'
import { invoke } from '@tauri-apps/api/core'
import {
  BaseDirectory,
  create,
  exists,
  mkdir,
  readDir,
  remove,
  writeFile,
} from '@tauri-apps/plugin-fs'
import { showLoading } from '@/utils/loading'
import { useI18n } from '@/i18n'

interface Props {
  frameList: FrameInfo[]
  lastHoverIndex: number
  fps: number
  setFps: (fps: number) => void
  onExportSpriteSheet: () => void
  onExportImageList: () => void
}
const DisplayView = (props: Props) => {
  const { t } = useI18n()
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const frameValueRef = useRef<HTMLDivElement>(null)
  const canvasCtx = useRef<CanvasRenderingContext2D | null>(null)
  const imageFrameList = useRef<HTMLImageElement[]>([])
  const [canvasSize, setCanvasSize, canvasSizeRef] = useStateRef({
    width: 200,
    height: 200,
  })
  const [play, setPlay] = useState(false)
  const { fps, setFps } = props
  const [fpsInputText, setFpsInputText] = useState('10')

  useEffect(() => {
    const fps = +fpsInputText
    if (!Number.isNaN(fps) && fps > 0) {
      setFps(fps)
    }
  }, [fpsInputText])

  useEffect(() => {
    const task = async () => {
      if (props.frameList.length != 0) {
        const info = await loadImageInfo(props.frameList[0].url)
        setCanvasSize({
          width: info.width,
          height: info.height,
        })
        canvasRef.current.width = info.width
        canvasRef.current.height = info.height
      } else {
        setCanvasSize({ width: 200, height: 200 })
        canvasRef.current.width = 200
        canvasRef.current.height = 200
      }
    }
    task()
  }, [props.frameList])
  useEffect(() => {
    if (play) return
    draw(props.lastHoverIndex)
  }, [props.frameList, play, props.lastHoverIndex])
  useEffect(() => {
    canvasCtx.current = canvasRef.current.getContext('2d')
    canvasCtx.current.imageSmoothingEnabled = false
  }, [])
  function renderFrameText(frame: number) {
    frameValueRef.current.innerHTML = `${Math.min(
      frame + 1,
      props.frameList.length
    )}/${props.frameList.length}`
  }
  const draw = (frame = 0) => {
    renderFrameText(frame)
    if (frame < 0 || frame >= imageFrameList.current.length) {
      return
    }
    const ctx = canvasCtx.current
    const w = canvasSizeRef.current.width
    const h = canvasSizeRef.current.height
    if (props.frameList.length == 0) {
      return
    }
    ctx.clearRect(0, 0, w, h)
    const img = imageFrameList.current[frame]
    const imageW = img.naturalWidth
    const imageH = img.naturalHeight
    if (imageW === 0 && imageH === 0) {
      //图片可能已失效
      console.warn('图片可能已失效')
      return
    }
    ctx.drawImage(img, 0, 0, imageW, imageH, 0, 0, w, h)
  }
  // drawHandle
  useEffect(() => {
    let isEnd = false
    const task = async () => {
      imageFrameList.current = await imageLoadManager.loadImageList(
        props.frameList
      )
      if (!play) {
        return
      }
      // 帧时间
      const frameTime = 1000 / fps
      let frame = 0
      let nowframeTime = 0
      let lastTime = 0
      const anim = (nowTime: number) => {
        const deltaTime = nowTime - lastTime
        lastTime = nowTime
        nowframeTime += deltaTime
        const addFrame = Math.floor(nowframeTime / frameTime)
        nowframeTime = nowframeTime % frameTime
        draw(frame)
        frame += addFrame
        if (props.frameList.length == 0) isEnd = true
        while (frame >= props.frameList.length && props.frameList.length != 0) {
          frame -= props.frameList.length
        }
        if (isEnd) return
        requestAnimationFrame(anim)
      }
      requestAnimationFrame(anim)
    }

    task().catch((e) => {
      console.error(e)
      // MessageBox.warn('播放异常', `${e}`)
    })
    return () => {
      isEnd = true
    }
  }, [fps, props.frameList, play])

  async function onExportSpriteSheet() {
    props.onExportSpriteSheet()
  }
  async function onExportImageList() {
    props.onExportImageList()
  }
  return (
    <div className="DisplayView">
      <div className="DisplayView-inner">
        <CustomCanvas className="canvas" ref={canvasRef} />
        <ripple-button className="play-box" onClick={() => setPlay(!play)}>
          {play ? <PauseSvg /> : <PlaySvg />}
        </ripple-button>
        <div className="detail-view">
          <div className="input-box">
            <div className="label">
              <label>{t('frame')}</label>
            </div>
            <div className="frame" ref={frameValueRef}></div>
          </div>
          <div className="input-box">
            <div className="label">
              <label>{t('animationSize')}</label>
            </div>
            <div>{`${canvasSize.width} x ${canvasSize.height}`}</div>
          </div>
          <div className="input-box">
            <div className="label">
              <label>FPS</label>
            </div>
            <input
              type="number"
              onChange={(e) => {
                setFpsInputText(e.target.value)
              }}
              min={1}
              max={200}
              className="input"
              value={fpsInputText}></input>
          </div>
          <div
            style={{
              height: 30,
            }}></div>
        </div>
      </div>
    </div>
  )
}
export default DisplayView
